package com.zgis.module.bas.util.encrypt;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 修改记录:
 * 24-09-29     zhengchaojun             首次创建
 */

/**
 * 类描述：base64类
 */
public class Base64
{
    private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();

    public static String encode(byte[] data) throws Exception
    {
        int           start = 0;
        int           len   = data.length;
        StringBuilder buf   = new StringBuilder(data.length * 3 / 2);
        int           end   = len - 3;
        int           i     = start;
        int           n     = 0;

        int d;
        while (i <= end)
        {
            d = (data[i] & 255) << 16 | (data[i + 1] & 255) << 8 | data[i + 2] & 255;
            buf.append(legalChars[d >> 18 & 63]);
            buf.append(legalChars[d >> 12 & 63]);
            buf.append(legalChars[d >> 6 & 63]);
            buf.append(legalChars[d & 63]);
            i += 3;
            if (n++ >= 14)
            {
                n = 0;
            }
        }

        if (i == start + len - 2)
        {
            d = (data[i] & 255) << 16 | (data[i + 1] & 255) << 8;
            buf.append(legalChars[d >> 18 & 63]);
            buf.append(legalChars[d >> 12 & 63]);
            buf.append(legalChars[d >> 6 & 63]);
            buf.append("=");
        }
        else if (i == start + len - 1)
        {
            d = (data[i] & 255) << 16;
            buf.append(legalChars[d >> 18 & 63]);
            buf.append(legalChars[d >> 12 & 63]);
            buf.append("==");
        }

        return new String(buf.toString().getBytes(), "UTF-8");
    }

    private static int decode(char c)
    {
        if (c >= 'A' && c <= 'Z')
        {
            return c - 65;
        }
        else if (c >= 'a' && c <= 'z')
        {
            return c - 97 + 26;
        }
        else if (c >= '0' && c <= '9')
        {
            return c - 48 + 26 + 26;
        }
        else
        {
            switch (c)
            {
                case '+':
                    return 62;
                case '/':
                    return 63;
                case '=':
                    return 0;
                default:
                    throw new RuntimeException("unexpected code: " + c);
            }
        }
    }

    public static byte[] decode(String s)
    {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        try
        {
            decode(s, bos);
        } catch (IOException var5)
        {
            throw new RuntimeException();
        }

        byte[] decodedBytes = bos.toByteArray();

        try
        {
            bos.close();
        } catch (IOException var4)
        {
            IOException ex = var4;
            System.err.println("Error while decoding BASE64: " + ex.toString());
        }

        return decodedBytes;
    }

    private static void decode(String s, OutputStream os) throws IOException
    {
        int i   = 0;
        int len = s.length();

        while (true)
        {
            while (i < len && s.charAt(i) <= ' ')
            {
                ++i;
            }

            if (i == len)
            {
                break;
            }

            int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12) + (decode(s.charAt(i + 2)) << 6) + decode(s.charAt(i + 3));
            os.write(tri >> 16 & 255);
            if (s.charAt(i + 2) == '=')
            {
                break;
            }

            os.write(tri >> 8 & 255);
            if (s.charAt(i + 3) == '=')
            {
                break;
            }

            os.write(tri & 255);
            i += 4;
        }

    }

    public static String filter(String str)
    {
        String       output = "";
        StringBuffer sb     = new StringBuffer();

        for (int i = 0; i < str.length(); ++i)
        {
            int asc = str.charAt(i);
            if (asc != '\n' && asc != '\r')
            {
                sb.append(str.subSequence(i, i + 1));
            }
        }

        return new String(sb);
    }
}
